package com.monitor.web.common.token;

import com.alibaba.fastjson.JSONObject;
import com.monitor.commons.redis.RedisUtil;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.Date;

/**
 * @author sunke
 * @Date 2019/11/12 10:50
 * @description
 */

@Component
public class JwtsUtil {


    public static String STAFF_HEADER_KEY = "authorization";
    public static String STAFF_WPS_HEADER_KEY = "x-wps-weboffice-token";//wps
    public static String STAFF_HEADER_KEY_PREFIX = "stafftoken ";
    public static String STAFF_KEY_REDIS = "ztjckj_staff_website";
    public static String STAFF_SECRET = "thisIsASecretKeyThatShouldBeLongAndComplexEnoughForSecuritythisIsASecretKeyThatShouldBeLongAndComplexEnoughForSecuritythisIsASecretKeyThatShouldBeLongAndComplexEnoughForSecuritythisIsASecretKeyThatShouldBeLongAndComplexEnoughForSecuritythisIsASecretKeyThatShouldBeLongAndComplexEnoughForSecuritythisIsASecretKeyThatShouldBeLongAndComplexEnoughForSecuritythisIsASecretKeyThatShouldBeLongAndComplexEnoughForSecuritythisIsASecretKeyThatShouldBeLongAndComplexEnoughForSecuritythisIsASecretKeyThatShouldBeLongAndComplexEnoughForSecurity";

    public static String TOKEN_KEY_REDIS = "token_key_redis";

    public String setAdminToken(AdminToken adminToken, HttpServletResponse response) {
        String token = createAdminToken(adminToken, System.currentTimeMillis());
        response.setHeader(JwtsUtil.STAFF_HEADER_KEY, token);
        return token;
    }

    public String createAdminToken(AdminToken adminToken, long currentTime) {
        adminToken.setCreateTime(currentTime);
        return createToken(JSONObject.toJSONString(adminToken), STAFF_SECRET, currentTime, STAFF_HEADER_KEY_PREFIX);
    }

    public AdminToken parseAdminToken(String userToken) {
        String token = parseJWT(userToken, STAFF_SECRET, STAFF_HEADER_KEY_PREFIX);
        if (token == null) {
            return null;
        }
        try {
            return JSONObject.parseObject(token, AdminToken.class);
        } catch (Exception e) {
        }
        return null;
    }


    @Resource
    private RedisUtil redisUtil;
//
//
//    @Value("${debug}")
//    private boolean debug;
//
//    public boolean isDebug() {
//        return debug;
//    }
//
//    public String setStaffToken(StaffToken staffToken, HttpServletResponse response) {
//
//        String token = createStaffToken(staffToken, System.currentTimeMillis());
//
//        response.setHeader(JwtsUtil.STAFF_HEADER_KEY, token);
//
//        return token;
//
//    }
//
//    /**
//     * 得到用户登录类型
//     *
//     * @param request
//     * @return
//     */
//    public int getRoleFlag(HttpServletRequest request) {
//        StaffToken token = getStaffToken(request);
//        try {
////            return token.getRoleFlag();
//        } catch (Exception e) {
//
//        }
//        return 0;
//
//    }
//
//    public String getDeptId(HttpServletRequest request) {
//        StaffToken token = getStaffToken(request);
//        try {
////            return token.getDeptId();
//        } catch (Exception e) {
//
//        }
//        return "";
//
//    }
//
//
//    public StaffToken getStaffToken(HttpServletRequest request) {
//
//
//        String headerToken = request.getHeader(JwtsUtil.STAFF_HEADER_KEY);
//
//        if (debug) {
//            StaffToken staffToken = new StaffToken();
//            staffToken.setUsername("admin");
//            staffToken.setStaffId("1");
//
//            return staffToken;
//
//        }
//
////        if (StringUtil.isEmpty(headerToken)) {
////            headerToken = request.getHeader(JwtsUtil.STAFF_WPS_HEADER_KEY);
////
////        }
//
//
//        return parseStaffToken(headerToken);
//
//    }
//
//    public String getStaffId(HttpServletRequest request) {
//
//        StaffToken token = getStaffToken(request);
//        try {
//            return token.getStaffId();
//        } catch (Exception e) {
//
//        }
//        return "";
//
//    }
//
//
//    public String getStaffTruename(HttpServletRequest request) {
//
//        StaffToken token = getStaffToken(request);
//        try {
//            return token.getTruename();
//        } catch (Exception e) {
//
//        }
//        return "";
//
//    }
//
//
//    /**
//     * 移除
//     *
//     * @param token
//     */
//    public void removeToken(Token token) {
//
//        if (token == null) {
//            return;
//        }
//        try {
//
//            String redisKey = token.getRedisKey();
//            redisUtil.del(redisKey);
//
//        } catch (Exception e) {
//
//        }
//
//    }
//

    /**
     * 判断是否要刷新
     * 5分钟内的需要刷新
     *
     * @param timeToken
     * @return
     */
    public boolean isRefreshToken(Token timeToken) {
        try {
            return System.currentTimeMillis() - timeToken.getCreateTime() > 60 * 5 * 1000;
        } catch (Exception e) {
        }
        return true;
    }

//    /**
//     * 个人token解密
//     *
//     * @param userToken
//     * @return
//     */
//    public PersonToken parsePersonToken(String userToken) {
//        String token = parseJWT(userToken, PERSON_SECRET, PERSON_HEADER_KEY_PREFIX);
//        if (token == null) {
//            return null;
//        }
//        try {
//            return JSONObject.parseObject(token, PersonToken.class);
//        } catch (Exception e) {
//        }
//        return null;
//    }
//
//
//    public StaffToken parseStaffToken(String userToken) {
//        String token = parseJWT(userToken, STAFF_SECRET, STAFF_HEADER_KEY_PREFIX);
//        if (token == null) {
//            return null;
//        }
//        try {
//            return JSONObject.parseObject(token, StaffToken.class);
//        } catch (Exception e) {
//        }
//        return null;
//    }
//
//    /**
//     * 创建个人token
//     *
//     * @param personToken
//     * @param currentTime
//     * @return
//     */
//    public String createPersonToken(PersonToken personToken, long currentTime) {
//        personToken.setCreateTime(currentTime);
//        return createToken(JSONObject.toJSONString(personToken), PERSON_SECRET, currentTime, PERSON_HEADER_KEY_PREFIX);
//    }
//
//
//    public String createStaffToken(StaffToken staffToken, long currentTime) {
//        staffToken.setCreateTime(currentTime);
//        return createToken(JSONObject.toJSONString(staffToken), STAFF_SECRET, currentTime, STAFF_HEADER_KEY_PREFIX);
//    }
//
//
//    /**
//     * 管理员token解密
//     *
//     * @param userToken
//     * @return
//     */
//    public AdminToken parseAdminToken(String userToken) {
//        String token = parseJWT(userToken, ADMIN_SECRET, ADMIN_HEADER_KEY_PREFIX);
//        if (token == null) {
//            return null;
//        }
//        try {
//            return JSONObject.parseObject(token, AdminToken.class);
//        } catch (Exception e) {
//
//        }
//        return null;
//    }
//

    /**
     * 解密
     *
     * @param jsonWebToken
     * @param
     * @return
     */
    private String parseJWT(String jsonWebToken, String secret, String prefix) {
        try {
            Key key = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), SignatureAlgorithm.HS256.getJcaName());


            String userToken =
                    Jwts.parser()
                            .setSigningKey(key)
                            .build()
                            .parseClaimsJws(jsonWebToken.replace(prefix, ""))

                            .getBody()

                            .getSubject();

            if (userToken == null) {
                return null;
            }
            String redisKey = JSONObject.parseObject(userToken, Token.class).getRedisKey();
            if (redisUtil.get(redisKey) == null) {
                return null;
            }
            return userToken;
        } catch (Exception e) {
            return null;
        }

    }

    private String createToken(String token, String secret, long currentTime, String prefix) {

        Token timeToken = JSONObject.parseObject(token, Token.class);

        redisUtil.set(timeToken.getRedisKey(), token, 60 * 60 * 24 * 1000);

        // 生成一个对HS512算法足够安全的密钥
//        Key key = Keys.secretKeyFor(SignatureAlgorithm.HS512);
        Key key = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), SignatureAlgorithm.HS256.getJcaName());
        return prefix + Jwts.builder()
                .setSubject(token)
                .setExpiration(new Date(currentTime + 60 * 60 * 24 * 1000))
                .signWith(key, SignatureAlgorithm.HS512)
                .compact();
    }
//
//    /**
//     * 创建管理员token
//     *
//     * @param adminToken
//     * @param currentTime
//     * @return
//     */
//    public String createAdminToken(AdminToken adminToken, long currentTime) {
//        adminToken.setCreateTime(currentTime);
//        return createToken(JSONObject.toJSONString(adminToken), ADMIN_SECRET, currentTime, ADMIN_HEADER_KEY_PREFIX);
//    }

}
